<template>
  <div class="desktop-icon" :class="{selected: props.selected, dragging}"
    @click.stop="emit('select', props.icon)"
    @dblclick="$emit('open', icon)"
    @contextmenu.prevent="onContextMenu"
    @mousedown="onMouseDown"
    tabindex="0"
    :style="dragging ? 'z-index:10000;opacity:.7;' : ''"
  >
    <div class="icon-image">
      <img :src="icon.image" :alt="icon.name">
    </div>
    <div v-if="!isRenaming" class="icon-name" @click.stop="startRename">{{ icon.name }}</div>
    <input v-else class="icon-rename-input" v-model="renameValue" @blur="finishRename" @keyup.enter="finishRename" ref="renameInput" />
    <ContextMenu
      :visible="showMenu"
      :x="menuX"
      :y="menuY"
      :menu="menuList"
      @select="onMenuSelect"
      @close="showMenu = false"
    />
  </div>
</template>

<script setup>
import { ref, watch, nextTick } from 'vue'
import ContextMenu from './ContextMenu.vue'
const props = defineProps({
  icon: { type: Object, required: true },
  index: Number,
  selected: Boolean
})
console.log('DesktopIcon icon:', props.icon)
const emit = defineEmits(['open', 'rename', 'delete', 'select', 'drag-move', 'drag-end'])
// 拖动相关
const dragging = ref(false)
const offset = ref({ x: 0, y: 0 })
function onMouseDown(e) {
  if (e.button !== 0) return
  dragging.value = true
  offset.value = {
    x: e.clientX - props.icon.left,
    y: e.clientY - props.icon.top
  }
  document.addEventListener('mousemove', onMouseMove)
  document.addEventListener('mouseup', onMouseUp)
}
function onMouseMove(e) {
  if (!dragging.value) return
  const left = e.clientX - offset.value.x
  const top = e.clientY - offset.value.y
  emit('drag-move', { left, top }) // 拖动时自由移动
}
function onMouseUp(e) {
  if (!dragging.value) return
  dragging.value = false
  document.removeEventListener('mousemove', onMouseMove)
  document.removeEventListener('mouseup', onMouseUp)
  // 鼠标松开时，吸附到网格
  const left = e.clientX - offset.value.x
  const top = e.clientY - offset.value.y
  emit('drag-end', { left, top })
}
const showMenu = ref(false)
const menuX = ref(0)
const menuY = ref(0)
const isRenaming = ref(false)
const renameValue = ref('')
const renameInput = ref(null)
const menuList = [
  { label: '打开' },
  { label: '重命名' },
  { label: '删除' }
]
function onContextMenu(e) {
  menuX.value = e.clientX
  menuY.value = e.clientY
  showMenu.value = true
}
function onMenuSelect(item) {
  if (item.label === '重命名') startRename()
  else if (item.label === '删除') emit('delete', props.icon)
  else if (item.label === '打开') emit('open', props.icon)
}
function startRename() {
  isRenaming.value = true
  renameValue.value = props.icon.name
  showMenu.value = false
  nextTick(() => renameInput.value && renameInput.value.focus())
}
function finishRename() {
  if (renameValue.value && renameValue.value !== props.icon.name) {
    emit('rename', { icon: props.icon, newName: renameValue.value })
  }
  isRenaming.value = false
}
watch(() => props.icon.name, n => { if (!isRenaming.value) renameValue.value = n })
</script>

<style scoped lang="scss">
.desktop-icon {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 80px;
  cursor: pointer;
  position: absolute;
  user-select: none;
  .icon-image {
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    img {
      max-width: 100%;
      max-height: 100%;
    }
  }
  .icon-name {
    margin-top: 5px;
    color: white;
    text-align: center;
    font-size: 12px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
    padding: 2px 5px;
    border-radius: 3px;
    &:hover { background-color: rgba(0, 120, 215, 0.3); }
  }
  .icon-rename-input {
    margin-top: 5px;
    width: 70px;
    font-size: 12px;
    border-radius: 3px;
    border: 1px solid #0078d7;
    outline: none;
    padding: 2px 5px;
    text-align: center;
  }
  &.selected {
    background: rgba(0,120,215,0.25);
    border-radius: 8px;
    box-shadow: 0 0 0 2px #0078d7;
  }
  &.dragging {
    opacity: 0.7;
    z-index: 10000;
  }
}
</style>